package org.reborn.demo

import org.reborn.engine.app._
import org.reborn.engine.input._
import org.reborn.engine.input.jinput._
import org.reborn.engine.enums._
import org.reborn.engine.model.mesh._

import org.reborn.engine.render.texture._

import net.java.games.input.{Mouse => JIMouse, Component}

import org.reborn.utils.niobuffer.BufferUtil
import org.reborn.math._


import com.jogamp.opengl.util._
import com.jogamp.opengl.util.awt.TextRenderer
import javax.media.opengl._
import javax.media.opengl.fixedfunc.GLLightingFunc
import javax.media.opengl.glu._
import java.awt._
import java.awt.event._

object TextureImageTypes extends GLApp {

  def main(args:Array[String]){
	
	println("java.library.path = "+System.getProperty("java.library.path"))
	  
    val options = new GLAppOptions()
    options.title = "Texture Image Types Test"
    options.fullscreen = false
    options.debugGL = true
    
	this.startApp(options)
  }
  
  import GL._
  import GL2GL3._


  var dt = 0.0f;
  
  var delay = 0.0f;
  
  var rotX = 0.0f;
  var rotY = 0.0f;
  var zoom = 0.0f;
  
  val text = new TextRenderer(new Font("SansSerif", Font.BOLD, 20))

  var textures:Seq[(Texture2D,String)] = 
	  Array((null,"Test-RGB.png"),
	 		(null,"Test-RGBA.png"),
	 		(null,"Test-RGB.bmp"),
	 		(null,"Test-RGBA.bmp"),
	 		(null,"Test-RGB.jpg"),
	 		(null,"Test-RGBA.jpg"),
	 		(null,"Test-RGB.png"),
	 		(null,"Test-RGBA.png"),
	 		(null,"Test-RGB.bmp"),
	 		(null,"Test-RGBA.bmp"),
	 		(null,"Test-RGB.jpg"),
	 		(null,"Test-RGBA.jpg"))
  
  var texInd = 0;
  
  var cubeMeshId = -1;
  var sphereMeshId = -1;
  var torusMeshId = -1;
  var meshId = -1
  var displaying = "cube"
  var textureName = "cube"

  var fpsAvg = 0.0f;
  var secs = 0.0f
  var wire = false;
  
  override def initScene(drawable:GLAutoDrawable){
    val gl = drawable.getGL.getGL2
    import gl._
    
    import GLLightingFunc._
    
    glEnable(GL_DEPTH_TEST)
    glDepthFunc(GL_LEQUAL)
    glHint(GL2ES1.GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST)
    glClearColor(0.3f,0.3f,0.3f,1.0f)
    
    //Enable lighting
    glEnable(GL_LIGHTING)
    glShadeModel(GL_SMOOTH);
    glEnable(GL_COLOR_MATERIAL)
    glEnable(GL_LIGHT0)
    
    glLightfv(GL_LIGHT0,GL_POSITION,Array(1.0f,1.0f,1.0f,0.0f),0)
    glLightfv(GL_LIGHT0,GL_AMBIENT,Array(0.25f,0.25f,0.25f,1.0f),0)
    glLightfv(GL_LIGHT0,GL_DIFFUSE,Array(1.0f,1.0f,1.0f,1.0f),0)
    glLightfv(GL_LIGHT0,GL_SPECULAR,Array(1.0f,1.0f,1.0f,1.0f),0)
    
    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
    glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,Array(1.0f,1.0f,1.0f,1.0f),0)
    glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,Array(0.1f,0.1f,0.1f,0.0f),0)
    //glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,180.0f)
    
    
    //Create the Cube Mesh
    var mesh = MeshShapes.Square(1.0f)
	cubeMeshId = util.meshRenderer.register(gl,mesh,UpdateFrequency.Rarely)
	
	//Create the Sphere Mesh
	mesh = MeshShapes.Sphere(36,36,0.5f)
	sphereMeshId = util.meshRenderer.register(gl,mesh,UpdateFrequency.Rarely)
	
	//Create the Torus Mesh
	mesh = MeshShapes.Torus(36,36,0.15f,0.5f)
	torusMeshId = util.meshRenderer.register(gl,mesh,UpdateFrequency.Rarely)
	
	meshId = cubeMeshId
	
	//The 2D Texture
	textures = textures.map{(texAndFile) =>
	  val (texture,file) = texAndFile
      (TextureManager.Texture2D(gl,"classpath:textures/ImageTextures/"+file),file)
    }
	
  }
  
  override def updateLogic(seconds:Float){
    this.dt = seconds

    delay += seconds
    
    val mouse = input.mouse
    val keyboard = input.keyboard
    
    fpsAvg = ((25.0f * fpsAvg) + seconds) / 26.0f
    
    if(mouse.leftButton.pressed)
    {
    	rotY += 1.0f * mouse.changeX.value
    	rotX += 1.0f * mouse.changeY.value
    }
    
    if(keyboard.keydown(Keyboard.Keys.S)){
      meshId = sphereMeshId
      displaying = "sphere"
    }
      
    if(keyboard.keydown(Keyboard.Keys.C)){
      meshId = cubeMeshId
      displaying = "cube"
    }
    
    if(keyboard.keydown(Keyboard.Keys.T)){
      meshId = torusMeshId
      displaying = "torus"
    }
    	
    if(delay >= 0.2f){
      if(texInd < textures.size-1 && keyboard.keydown(Keyboard.Keys.Up)){ 
    	texInd += 1
    	delay = 0.0f
      }
      if(texInd > 0 && keyboard.keydown(Keyboard.Keys.Down)){ 
    	texInd -= 1
    	delay = 0.0f
      }
    }
    
    if(keyboard.keydown(Keyboard.Keys._2)) texInd = 1
    if(keyboard.keydown(Keyboard.Keys._3)) texInd = 2
    if(keyboard.keydown(Keyboard.Keys._4)) texInd = 3
    if(keyboard.keydown(Keyboard.Keys._5)) texInd = 4
    if(keyboard.keydown(Keyboard.Keys._6)) texInd = 5
    
    wire = mouse.rightButton.pressed
   
    secs+=dt
  }
  
  override def renderScene(drawable:GLAutoDrawable){
    val gl = drawable.getGL.getGL2
    import gl._
    
    import GLLightingFunc._
    
    val shininess = (31.0f * math.cos(secs).asInstanceOf[Float]) + 96.0f
    math.max(math.min(128.0f,shininess),0.0f)
    glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,shininess)
    
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT)
    
    if(wire)
    	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    else
    	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    
    //Render the cube with 2D texture
    glEnable(GL_TEXTURE_2D);
    textures(texInd)._1.bind(gl)
    glLoadIdentity();
    glTranslatef(0.0f,0.0f,-2.5f + zoom)
    glRotatef(rotY,0.0f,1.0f,0.0f)
    glRotatef(rotX,1.0f,0.0f,0.0f)
    glColor3f(1.0f,1.0f,1.0f)
    util.meshRenderer.render(gl,meshId)
    glDisable(GL_TEXTURE_2D);
    
    if(wire)
    	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    	
    //Render the FPS text
    val mouse = input.mouse
    val keyboard = input.keyboard
    text beginRendering(drawable.getWidth, drawable.getHeight)
    text setColor(1.0f, 1.0f, 1.0f, 1.0f);
    text draw("" + 1.0f/fpsAvg,0,0);
    text draw("Object: " + displaying,0,18);
    text draw("Texture: " + textures(texInd)._2,0,36);
    
    text endRendering
      
    glFlush
  }

}